home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Information / CSMP Digest / volume 1 / csmp-v1-173.txt < prev    next >
Text File  |  1992-12-31  |  49KB  |  1,439 lines

  1. C.S.M.P. Digest             Sun, 04 Oct 92       Volume 1 : Issue 173
  2.  
  3. Today's Topics:
  4.  
  5.     Beginner's question on StandardPutFile
  6.     Hacking Think_C Malloc, need big free!
  7.     GetPictInfo bug with QuickTime Picts?
  8.     Is there a PD console package for Mac?
  9.     Fortran callable rountines in THINK C
  10.     Dylan and Newton PDAs
  11.     Packing Rects into the smallest possible container
  12.     Directory Scan Revisited
  13.  
  14.  
  15.  
  16. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  17.  
  18. The digest is a collection of article threads from the internet newsgroup
  19. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  20. regularly and want an archive of the discussions.  If you don't know what a
  21. newsgroup is, you probably don't have access to it.  Ask your systems
  22. administrator(s) for details.  (This means you can't post questions to the
  23. digest.)
  24.  
  25. Each issue of the digest contains one or more sets of articles (called
  26. threads), with each set corresponding to a 'discussion' of a particular
  27. subject.  The articles are not edited; all articles included in this digest
  28. are in their original posted form (as received by our news server at
  29. cs.uoregon.edu).  Article threads are not added to the digest until the last
  30. article added to the thread is at least one month old (this is to ensure that
  31. the thread is dead before adding it to the digest).  Article threads that
  32. consist of only one message are generally not included in the digest.
  33.  
  34. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
  35. [128.223.8.8] in the directory /pub/mac/csmp-digest.  Be sure to read the
  36. file /pub/mac/csmp-digest/README before downloading any files.  The most
  37. recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
  38. directory /info-mac/digest/csmp.  If you don't have ftp capability, the sumex
  39. archive has a mail server; send a message with the text '$MACarch help' (no
  40. quotes) to LISTSERV@ricevm1.rice.edu for more information.
  41.  
  42. The digest is also available via email.  Just send a note saying that you
  43. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  44. automatically receive each new issue as it is created.  Sorry, back issues
  45. are not available through the mailing list.
  46.  
  47. Send administrative mail to mkelly@cs.uoregon.edu.
  48.  
  49.  
  50. -------------------------------------------------------
  51.  
  52. From: ewu1@husc8.harvard.edu (Elwin Wu)
  53. Subject: Beginner's question on StandardPutFile
  54. Date: 1 Sep 92 12:01:59 GMT
  55.  
  56. I'm having trouble getting the volume reference number returned by the
  57. StandardPutFile routine.  I want to use SetVol and my code typically
  58. looks something like this (I'm using Think C 5.0):
  59.  
  60.     StandardPutFile(prompt,defaultName,&theReply);
  61.     SetVol(theReply.sfFile.vRefNum);
  62.  
  63. Should I use something other that SetVol???  Any help would be
  64. appreciated.  Thanks
  65.  
  66. +++++++++++++++++++++++++++
  67.  
  68. From: keith@taligent.com (Keith Rollin)
  69. Organization: Taligent
  70. Date: Tue, 1 Sep 1992 18:39:23 GMT
  71.  
  72. In article <ewu1.715348919@husc8>, ewu1@husc8.harvard.edu (Elwin Wu) writes:
  73. > I'm having trouble getting the volume reference number returned by the
  74. > StandardPutFile routine.  I want to use SetVol and my code typically
  75. > looks something like this (I'm using Think C 5.0):
  76. >     StandardPutFile(prompt,defaultName,&theReply);
  77. >     SetVol(theReply.sfFile.vRefNum);
  78. > Should I use something other that SetVol???  Any help would be
  79. > appreciated.  Thanks
  80.  
  81. IMHO, you should replace the line containing SetVol with a blank line.
  82. "theReply.sfFile" contains everything you need to access the file. If you want
  83. to open the data for, call FSpOpenDF. If you want to open the resource fork,
  84. call FSpOpenResFile. You don't need to change the default directory.
  85.  
  86. If, for some arcane reason, you feel you _do_ need to change the default
  87. directory, do it thusly:
  88.  
  89.     GetVol(nil, &oldVol);
  90.     HSetVol(nil, theReply.sfFile.vRefNum, theReply.sfFile.parID);
  91.     DoMyStuff();
  92.     SetVol(nil, oldVol);
  93.  
  94. - --
  95. Keith Rollin
  96. Phantom Programmer
  97. Taligent, Inc.
  98.  
  99.  
  100. +++++++++++++++++++++++++++
  101.  
  102. From: d88-jwa@byse.nada.kth.se (Jon W{tte)
  103. Organization: Royal Institute of Technology, Stockholm, Sweden
  104. Date: Tue, 1 Sep 1992 23:10:56 GMT
  105.  
  106. @husc8.harvard.edu (Elwin Wu) writes:
  107.  
  108.    I'm having trouble getting the volume reference number returned by the
  109.    StandardPutFile routine.  I want to use SetVol and my code typically
  110.    looks something like this (I'm using Think C 5.0):
  111.  
  112.        StandardPutFile(prompt,defaultName,&theReply);
  113.        SetVol(theReply.sfFile.vRefNum);
  114.  
  115.    Should I use something other that SetVol???  Any help would be
  116.    appreciated.  Thanks
  117.  
  118.  
  119. Why on EARTH would you do this?
  120.  
  121. You're on System 7, since you use StandardPutFile, and there is
  122. not a single thing under System 7 that requires a volume or wdRefNum.
  123.  
  124. Use the FSpCalls; they're there for you and the FSSpec returned
  125. in theReply is all you need. (If you want to do a SetVol to open
  126. a file using fopen:
  127. 1) Don't use fopen since it stinks on the mac... or
  128. 2) Do a HGetVol, HSetVol, fopen, and HSetVol back to what you
  129.    got from HGetVol)
  130.  
  131. - -- 
  132. Jon W{tte, h+@nada.kth.se, Sweden, Phone +46-8-107069
  133. White, Literate, Employed, Higher-Educated, Male, Straight and Not Poor.
  134. I must be a bad guy.
  135.  
  136. ---------------------------
  137.  
  138. From: brunner@crchh447.bnr.ca (James Brunner)
  139. Subject: Hacking Think_C Malloc, need big free!
  140. Organization: Bell-Northern Research, Richardson, Tx
  141. Date: Mon, 31 Aug 1992 22:36:42 GMT
  142.  
  143. Howdy, I'm working on a kludge where I am combining several UNIX utilities.
  144. Each of these allocates memory and it gets freed automatically at exit(0).
  145. I would like to be able to free all malloc-allocated memory between calls
  146. to these utils.  I've looked at alloc.c but it's all in asm and hard to read.
  147.  
  148. How can the library be modified to add a free_all routine?
  149. - -- 
  150. - ---------------------------------------------------------------------------
  151. Jim Brunner - (brunner@bnr.ca)
  152. All opinions are my own and have nothing whatsoever to do with BNR, NT,
  153. NTI, Bell Canada, or any of the BCE corporations or affiliates.
  154.  
  155. +++++++++++++++++++++++++++
  156.  
  157. From: reed@snake.tc.cornell.edu (Michael G. Reed)
  158. Organization: Cornell National Supercomputing Facility
  159. Date: Tue, 1 Sep 1992 12:06:52 GMT
  160.  
  161. In article <1992Aug31.223642.1858@bnr.ca>, brunner@crchh447.bnr.ca (James Brunner) writes:
  162. |> Howdy, I'm working on a kludge where I am combining several UNIX utilities.
  163. |> Each of these allocates memory and it gets freed automatically at exit(0).
  164. |> I would like to be able to free all malloc-allocated memory between calls
  165. |> to these utils.  I've looked at alloc.c but it's all in asm and hard to read.
  166. |> 
  167. |> How can the library be modified to add a free_all routine?
  168.  
  169. If I remember correctly, ThinkC's malloc (and calloc for that matter) are 
  170. simply mapped into calls to the memory manager call NewPtr.  Therefore, the
  171. only way to "free-all" would be to free everything in the heap (which would
  172. be VERY bad, because you would free your code as well...).  I'm not sure how
  173. to do it (I don't have IMs here at work yet), and for that matter, I'm not
  174. sure this would even work, but I think you could create a new heap, set your
  175. current heap (zone?) into that heap, do all your allocation and then simply
  176. destroy the heap for your "free-all".  Sound plausible?
  177.  
  178. - -Michael
  179.  
  180. - -----------------------------------------------------------------------------
  181. Michael G. Reed                                  (reed@Theory.TC.Cornell.edu)
  182. Cornell National Supercomputing Facility                       (607)/254-8806
  183. - -----------------------------------------------------------------------------
  184.         Why be normal, it's boring; and boring people should be shot.
  185.  
  186. Note:  These are not the views of my employer (and probably not mine either).
  187.  
  188. ---------------------------
  189.  
  190. From: mpradhan@medicine.adelaide.edu.au (Malcolm Pradhan)
  191. Subject: GetPictInfo bug with QuickTime Picts?
  192. Date: 28 Aug 92 00:12:22 GMT
  193. Organization: Faculty of Medicine, University of Adelaide
  194.  
  195. Hello all,
  196.  
  197.  I'm using GetPictInfo to request a 256 colour palette from a 32 bit
  198. image. Normally this works fine and I simply set the window's palette
  199. to the one returned by GetPictInfo and copybits using ditherCopy, ie.
  200.  
  201.     err= GetPictInfo((PicHandle)pictH, &pictInfoRec, returnPalette,
  202.                         256, popularMethod, 0);
  203.     SetPalette(myWindow, pictInfoRec.thePalette, TRUE);
  204.  
  205.  I have found that if the PICT is quicktime compressed (JPEG, Video)
  206. no palette is returned and no error is signalled from the GetPictInfo
  207. call - pretty frustrating.
  208.  
  209.  The only way I can see of getting around this is to create an gworld,
  210. draw the compressed PICT into it and then GetPixMapInfo. Tedious and
  211. memory intensive!
  212.  
  213.  Has anyone found a way of getting a clut or palette from a QT compressed
  214. PICT? Is this a known bug which will soon be fixed in System 7.1 and
  215. QT 1.5? :-)
  216.  
  217. Regards
  218. Malcolm
  219. _________________________________________________________________
  220.     Malcolm Pradhan
  221.     Medical Computing, Faculty of Medicine         _--_|\
  222.     University of Adelaide, South Australia       /      \
  223.     InterNet: mpradhan@medicine.adelaide.edu.au   \_.--x_/
  224.     Fax: +618 223 2076  :x marks the spot:              v
  225.  
  226. +++++++++++++++++++++++++++
  227.  
  228. From: pxi@lesti.hut.fi (Pekka M Salonen)
  229. Organization: Helsinki University of Technology, Finland
  230. Date: 1 Sep 92 23:17:10
  231.  
  232.  
  233. In article <8350@sirius.ucs.adelaide.edu.au> mpradhan@medicine.adelaide.edu.au (Malcolm Pradhan) writes:
  234. ...
  235. <    I have found that if the PICT is quicktime compressed (JPEG, Video)
  236. <   no palette is returned and no error is signalled from the GetPictInfo
  237. <   call - pretty frustrating.
  238.  
  239. <    The only way I can see of getting around this is to create an gworld,
  240. <   draw the compressed PICT into it and then GetPixMapInfo. Tedious and
  241. <   memory intensive!
  242.  
  243. <    Has anyone found a way of getting a clut or palette from a QT compressed
  244. <   PICT? Is this a known bug which will soon be fixed in System 7.1 and
  245. <   QT 1.5? :-)
  246.  
  247. <   Regards
  248. <   Malcolm
  249.  
  250. In Mac Q&A in develop issue 11 this was discussed, here's a quote:
  251.  
  252. "Q Is it my imagination, or does GetPictInfo return a bit depth of 1 on 
  253. QuickTime compressed PICT files?
  254.  
  255. A Yep! This is what's happening: The Picture Utilities Package doesn't know of 
  256. the QuickTime Compressed Pixmap opcode (0x8200), so it just skips over the 
  257. opcode's data; then it finds the PackBitRect opcode containing the 
  258. black-and-white pseudo-alert that you get when you draw the picture on a 
  259. machine that doesn't have QuickTime installed, and GetPictInfo reports back 
  260. this alert.
  261.  
  262. Trivia: When QuickTime is installed, it displays the compressed image and 
  263. then ignores the following PackBitRect since QuickTime knows it's only 
  264. the black-and-white alert."
  265.  
  266. Reprinted here sans permission, don't think anybody will mind.
  267. So this is a known thingie. That's all I know.
  268.  
  269.     pekka
  270.  
  271.  
  272.  
  273.  
  274. - --
  275. ha!
  276.  
  277. ---------------------------
  278.  
  279. From: vladimir@intrepid.intrepid.com (Vladimir Vukicevic)
  280. Subject: Is there a PD console package for Mac?
  281. Date: 30 Aug 92 19:13:35 GMT
  282. Organization: Intrepid Technology, Inc.
  283.  
  284. Does anyone know of a PD 'console' package, like THINK provides? I have THINK C,
  285. but I am really looking for the source of one, because I would like to add
  286. more features (I am writing a CLI). If there isn't one, does anyone know
  287. of a way to do I/O on the mac (with, for example, printf() & fgets()...)?
  288. I was thinkning of creating a window, and then using TextEdit, but I can't
  289. figure out a way to make the prompt non-overwriteable, and how to get a specific
  290. part of the text. Any ideas? Suggestions? Comments?
  291.  
  292.     - Vladimir
  293.     - vladimir@intrepid.com
  294.  
  295. - -- 
  296.  
  297. - -------------------------------------------------------------------------------
  298.         Internet................vladimir@intrepid.com
  299. ^[:r std.disclaimer
  300.  
  301. +++++++++++++++++++++++++++
  302.  
  303. From: siegel@world.std.com (Rich Siegel)
  304. Organization: GCC Technologies
  305. Date: Tue, 1 Sep 1992 12:39:59 GMT
  306.  
  307. In article <1992Aug30.191335.4377@intrepid.com> vladimir@intrepid.intrepid.com (Vladimir Vukicevic) writes:
  308. >Does anyone know of a PD 'console' package, like THINK provides? I have THINK C,
  309. >but I am really looking for the source of one, because I would like to add
  310. >more features (I am writing a CLI). If there isn't one, does anyone know
  311. >of a way to do I/O on the mac (with, for example, printf() & fgets()...)?
  312. >I was thinkning of creating a window, and then using TextEdit, but I can't
  313. >figure out a way to make the prompt non-overwriteable, and how to get a specific
  314. >part of the text. Any ideas? Suggestions? Comments?
  315.  
  316. The source for the ANSI library is included with THINK C; there's no 
  317. particular reason you can't use that as a basis.
  318.  
  319. R.
  320.  
  321.  
  322. - -- 
  323. - -----------------------------------------------------------------------
  324. Rich Siegel                              Internet: siegel@world.std.com
  325. Software Engineer & Toolsmith
  326. GCC Technologies
  327.  
  328. +++++++++++++++++++++++++++
  329.  
  330. From: bpb9204@tamsun.tamu.edu (Brent)
  331. Date: 1 Sep 92 18:14:39 GMT
  332. Organization: Texas A&M Univ., Inc.
  333.  
  334. vladimir@intrepid.intrepid.com (Vladimir Vukicevic) writes:
  335. |Does anyone know of a PD 'console' package, like THINK provides? I have THINK C,
  336. |but I am really looking for the source of one, because I would like to add
  337. |more features (I am writing a CLI). If there isn't one, does anyone know
  338. |of a way to do I/O on the mac (with, for example, printf() & fgets()...)?
  339. |I was thinkning of creating a window, and then using TextEdit, but I can't
  340. |figure out a way to make the prompt non-overwriteable, and how to get a specific
  341. |part of the text. Any ideas? Suggestions? Comments?
  342.  
  343.  
  344. Vladimir,
  345.  
  346. Good news!  I've done this exact thing and I posted info about it many months
  347. ago but got no response (nobody needed it then, I guess).  What I have done
  348. is to create a "shell" window that has a simple TextEdit area.  The
  349. area has a typical prompt printed that the user cannot change.  The user
  350. is allowed to type, edit, copy, paste, etc into this area and then when
  351. the user hits the <Enter> key, the program sucks the new text out that the
  352. user entered.  Processing is not done for the <Return> key;  therefore, the
  353. entered text may have line breaks in it.
  354.  
  355. The prompt text string is stored in a resource and can be changed.
  356.  
  357. There is also a basic routine to Print() strings to the window (what you
  358. put in the string to print is up to you -- use NumToStr(), sprintf(), 
  359. whatever).
  360.  
  361. I'll gladly make the source available to anybody interested.
  362.  
  363. - -Brent
  364.  
  365. +++++++++++++++++++++++++++
  366.  
  367. From: haney@moonshine.llnl.gov (Scott W. Haney)
  368. Date: 1 Sep 92 22:14:18 GMT
  369. Organization: Magnetic Fusion Energy - LLNL
  370.  
  371. [Stuff asking about a PD shell window]
  372.  
  373. >Vladimir,
  374.  
  375. >Good news!  I've done this exact thing and I posted info about it many months
  376. >ago but got no response (nobody needed it then, I guess).  What I have done
  377. >is to create a "shell" window that has a simple TextEdit area.  The
  378. >area has a typical prompt printed that the user cannot change.  The user
  379. >is allowed to type, edit, copy, paste, etc into this area and then when
  380. >the user hits the <Enter> key, the program sucks the new text out that the
  381. >user entered.  Processing is not done for the <Return> key;  therefore, the
  382. >entered text may have line breaks in it.
  383.  
  384. [...]
  385.  
  386. >I'll gladly make the source available to anybody interested.
  387.  
  388. >-Brent
  389.  
  390. Brent,
  391.   Please tell us how to get a copy of your shell package.  I could make
  392. use of this sort of thing today. One question: does it support sessions
  393. longer that 32K (a common limitation for things based on TextEdit)?
  394.  
  395. Scott
  396. - --
  397. - -------------------------------------------------------------------------
  398. Scott W. Haney        || Lawrence Livermore N'Lab || The above views are 
  399. haney@random.llnl.gov || P.O. Box 808;  L-644     || mine and not neces-
  400. (510) 423-6308        || Livermore, CA  94550     || sarily LLNL's.
  401.  
  402. +++++++++++++++++++++++++++
  403.  
  404. From: bpb9204@tamsun.tamu.edu (Brent)
  405. Organization: Texas A&M Univ., Inc.
  406. Date: Tue, 1 Sep 1992 23:24:24 GMT
  407.  
  408. haney@moonshine.llnl.gov (Scott W. Haney) writes:
  409. |
  410. | [..shell info deleted...]
  411. |
  412. |Brent,
  413. |  Please tell us how to get a copy of your shell package.  I could make
  414. |use of this sort of thing today. One question: does it support sessions
  415. |longer that 32K (a common limitation for things based on TextEdit)?
  416.  
  417. OK.  Let me just make a few comments about what exactly I have.
  418.  
  419. I think "package" is the wrong word; I tend to think of a package as a
  420. library.  What I *do* have is a small application that shows how to do
  421. this type of processing.  The runnable application is only some 8K in size,
  422. and the code is moderately readable.
  423.  
  424. What it does now is:  lets the user type their info in (whatever it may be).
  425. When the enter key is pressed, the program reads all the text entered after
  426. the prompt.  Everything *before* the prompt is deleted.
  427. What this does is allows the last "command" to remain displayed.  This is
  428. very hard to describe here; you'll have to check out the program.
  429. In other words, the text actually stored in the textedit record is rarely
  430. more than 1K; so yes, the program handles the 32k barrier fine.  This 
  431. "feature" of deleting old data is easily modifiable to store say, the last
  432. 16000 characters.
  433.  
  434. As far as getting it goes, if you would like a copy, please reply via
  435. email.  I will eventually post it to comp.binaries.mac, but it'd be quickest
  436. to email it to anyone who is interested and wants/needs it now.  The
  437. source and executable is only 44k (binhexed).
  438.  
  439. I'll compile a list of people and zap it out in a few days, OK?
  440.  
  441. - -Brent
  442.  
  443. ---------------------------
  444.  
  445. From: cconstantine@galaxy.gov.bc.ca
  446. Subject: Fortran callable rountines in THINK C
  447. Date: 1 Sep 92 11:30:40 -0700
  448. Organization: BC Systems Corporation
  449.  
  450. I will be working on a program with a friend of mine that will interface some
  451. Fortran code (Language Systems) and would like my C libraries to be callable
  452. form Fortran.  Is there a specific way I need to do this?  I'm using THINK C
  453. 5.0.2 on an LCII (now called a Perforama 400) and System 7.0.1 w/ tune-up.
  454.  
  455. Thanks muchly!!!!
  456. - -- 
  457. Carl B. Constantine
  458. CCONSTANTINE@galaxy.gov.bc.ca
  459.     "Opinions are mine only!!"
  460.  
  461. +++++++++++++++++++++++++++
  462.  
  463. From: jhl@naif.jpl.nasa.gov (Jay Lieske)
  464. Organization: Jet Propulsion Laboratory
  465. Date: Tue, 1 Sep 1992 21:14:01 GMT
  466.  
  467. In article <1992Sep1.113040.943@galaxy.gov.bc.ca> cconstantine@galaxy.gov.bc.ca
  468. writes:
  469. >I will be working on a program with a friend of mine that will interface some
  470. >Fortran code (Language Systems) and would like my C libraries to be callable
  471. >form Fortran.  Is there a specific way I need to do this?  I'm using THINK C
  472. >5.0.2 on an LCII (now called a Perforama 400) and System 7.0.1 w/ tune-up.
  473. >
  474. >Thanks muchly!!!!
  475. >-- 
  476. >Carl B. Constantine
  477. >CCONSTANTINE@galaxy.gov.bc.ca
  478. >    "Opinions are mine only!!"
  479. >
  480.  
  481. In principle, I think it can be done, but it's rather tough with Think
  482. products.  Specifically, I tried this a few years ago using Think Pascal.
  483. The basic problem is that Think compilers are case-sensitive and its
  484. linker is case-insensitive whereas the MPW Pascal compiler is case
  485. insensitive but the linker is case-sensitive.  For Pascal programs that
  486. means that the ENTRY points must be all caps.  One interesting and
  487. potentially useful side effect of all this is that Think and MPW libraries
  488. may be intermixed--for example MPW's NEWPTR is "different" from
  489. Think's NewPtr because of the capitalization.
  490.  
  491. At one time Rich Siegel mentioned that Think Pascal might look into
  492. the problem, but I don't believe they have done anything up to now.  It's
  493. much easier just to recompile things with MPW compilers (after using 
  494. Think's excellent debugging tools) and link with Language Systems Fortran.
  495.  
  496.  
  497. Jay H. Lieske                                            jhl@naif.jpl.nasa.gov
  498.  
  499.  
  500. +++++++++++++++++++++++++++
  501.  
  502. From: TOGE@SLACVM.SLAC.STANFORD.EDU (Nobukazu Toge)
  503. Date: 2 Sep 92 01:58:57 GMT
  504. Organization: Stanford Linear Accelerator Center
  505.  
  506. Carl -
  507.  
  508. LS Fortran knows to interface with MPW C, Pascal and so on.  See Appendix F
  509. (p.375) of LSF 3.0 manual.  So if you convert your ThC libraries into MPW
  510. you will be all set.  I understand that MPW .o -> ThC lib conversion is
  511. possible, but I'm not sure about the other way around [which is what you
  512. need].  Check out the ThC manual.
  513.  
  514. If it turns out not so straightforward you may consider porting
  515. your Th C source files and recompile them with MPW C.  The mac .h files
  516. on Th C v.5.0.x are very similar to (or identical to) MPW interfaces.
  517. Except,if you are accessing low memory globals by using LoMem.h in the
  518. {Think #includes} folder, you should modify them to use SysEqu.h. Otherwise
  519. strange errors will happen on MPW.  Another thing is A4/A5 world stuff, but
  520. that probably is a non-issue unless you are writing code resources, not
  521. ordinary library routines.
  522.  
  523. - - Nobu Toge (ex-SLAC, now-KEK. My opinions only).
  524.  
  525. ---------------------------
  526.  
  527. From: chrisv@runx.oz.au (Chris Velevitch)
  528. Subject: Dylan and Newton PDAs
  529. Organization: RUNX Un*x Timeshare.  Sydney, Australia.
  530. Date: Tue, 1 Sep 92 15:35:35 GMT
  531.  
  532. I have heard that there is a new programming language called
  533. Dylan, which is being used to build compact cross-platform
  534. applications for the Mac, Newton PDAs and Unix workstations.
  535. Is is available yet? If it is available, how does one test an
  536. application if you don's have access to a PDA? I also have
  537. heard that there is a new fully pre-emptive multitasking
  538. operation systems for the Newton called NewtOS. Will NewtOS
  539. be available for the Mac or a NewtOS emulator to allow
  540. testing of OS related functions?
  541. - -- 
  542. Chris Velevitch
  543. Internet: chrisv@runxtsa.runx.oz.au
  544. UUCP: ...!uunet!munnari!runxtsa.runx.oz.au!chrisv
  545. Voice: +61 2 906 6100, Fax: +61 2 906 6069
  546.  
  547. +++++++++++++++++++++++++++
  548.  
  549. From: joseph@joebloe.maple-shade.nj.us (Joseph Nathan Hall)
  550. Date: 2 Sep 92 04:01:08 GMT
  551. Organization: 5 Sigma Software
  552.  
  553.  
  554. In article <1992Sep1.153535.2391@runx.oz.au> (comp.sys.mac.programmer), chrisv@runx.oz.au (Chris Velevitch) writes:
  555. ) I have heard that there is a new programming language called
  556. ) Dylan, which is being used to build compact cross-platform
  557. ) applications for the Mac, Newton PDAs and Unix workstations.
  558. ) Is is available yet? [etc....]
  559.  
  560. This has been a topic off and on in MacWeek for a while now.  Apparently
  561. Apple is leaning toward supporting only large developers for the Newton.
  562. Apple would like to shape the initial product and perception quite
  563. carefully.  Whether that might prevent it from being useful, who knows.
  564.  
  565. There has also been some discussion about whether Dylan will be just
  566. too damned slow as an implementation language.
  567.  
  568. In any event, the shipping date has already started to slide a la
  569. System 7, so I wouldn't worry too much about writing yer own Newton
  570. apps yet.
  571.  
  572. uunet!joebloe!joseph   (609) 273-8200 day   joseph%joebloe@uunet.uu.net
  573. v   v  sssss | Certified Guru: all-grain brewing,| 2102 Ryan's Run East
  574.  v v  s   s  | C, synthesizer comp & arranging,  | Rt 38 & 41
  575.   v    sss   | photography. Also not a bad cook. | Maple Shade NJ 08052
  576. - -----My employer isn't paying for this, and my opinions are my own-----
  577.  
  578. ---------------------------
  579.  
  580. From: tj@kona.cs.ucla.edu (Tom Johnson)
  581. Subject: Packing Rects into the smallest possible container
  582. Date: 12 Aug 92 01:35:21 GMT
  583. Organization: UCLA Computer Science Department
  584.  
  585.  
  586. Hi-
  587.  
  588. I'm sure that what I'm about to ask has been covered in many books and
  589. in many articles, since it sounds like one of those typical cs/math puzzles.
  590. But I don't have any books that help, and I'm looking for some ideas.
  591. I'm not looking for the "perfect" algorithm, just something efficient
  592. and reasonable. So here goes my question:
  593.  
  594. I have a bunch of rectangular objects, and I would like to pack them into
  595. the smallest possible rectangular container (we're only dealing with 2
  596. dimensions here, I'm not concerned with 3d boxes).  How do I do this?
  597. The objects may all have different sizes. 
  598.  
  599. Any suggestions for algorithms? Ideas?
  600.  
  601. This shouldn't be too difficult, but I can't seem to come up with something
  602. I like.
  603.  
  604.   Tom
  605.  
  606. btw, I would imagine that this would become really interesting with
  607. other shapes, but all I really care about is rectangles.
  608. - -- 
  609. Tom Johnson             "They say Confucious does his crossword with a pen."
  610. tj@cs.ucla.edu                               -Tori Amos
  611.  
  612. +++++++++++++++++++++++++++
  613.  
  614. From: zben@ni.umd.edu (Charles B. Cranston)
  615. Organization: UM Home for the Terminally Analytical
  616. Date: Wed, 12 Aug 1992 20:26:24 GMT
  617.  
  618. In article <1992Aug12.013521.28314@cs.ucla.edu>,
  619. tj@kona.cs.ucla.edu (Tom Johnson) wrote:
  620.  
  621. > I have a bunch of rectangular objects, and I would like to pack them into
  622. > the smallest possible rectangular container (we're only dealing with 2
  623. > dimensions here, I'm not concerned with 3d boxes).  How do I do this?
  624. > The objects may all have different sizes. 
  625. > Any suggestions for algorithms? Ideas?
  626.  
  627. This sounds a lot like a two-dimensional version of what has come to be
  628. called "the knapsack problem" in computer science literature.  You might
  629. be able to find some work being done if you use this buzzword.
  630.  
  631. Actually, the knapsack problem is usually explained in terms of fitting
  632. the maximum amount of stuff in a knapsack of known size, i.e., given a
  633. set of integers {I} and a number N find the maximal subset {i} such
  634. that  sum({i}) <= N  or something like that.  In your case it is more
  635. like finding the minimal N which for the one-dimensional case is simply
  636. sum({I}).
  637.  
  638. The knapsack problem is thought to be NP-complete.  In fact, it was one
  639. of the other schemes besides the factoring problem (RSA) considered for
  640. use in public-key encryption algorithms...
  641.  
  642. zben@ni.umd.edu     -KA3ZDF
  643.  
  644. +++++++++++++++++++++++++++
  645.  
  646. From: root@lyra.scg.hac.com (Dave Fisher)
  647. Date: 1 Sep 92 23:10:02 GMT
  648. Organization: Hughes Aircraft Co., Carlsbad, CA
  649.  
  650. The "knapsack" problem is close; but a perfect fit of your problem
  651. is the VLSI problem called "2-D placement" or "bin packing".
  652.  
  653. Many algorithms have been published.  There are approaches that
  654. use optimization techniques, such as "greedy algorithms", "genetic
  655. algorithms", "spin-glass" (this one looked excellent but difficult),
  656. "simulated annealing", etc.  There have also been heuristic rule-based
  657. systems, straight algorithms, etc.
  658.  
  659. The best source for info is probably the conference proceedings for
  660. the "Design Automation Conference" (DAC), published annually.  Also try
  661. the journal called "VLSI".  Or ask a local VLSI CAD expert for some
  662. good references.
  663.  
  664. If you end up writing your own algorithm, here are a couple of tips:
  665. 1. Place larger blocks first
  666. 2. Try to find groups of 2 or more blocks which have a common width
  667.    or length and line them up -- this is very efficient.  
  668. 3. Allow for switching things around randomly, to try different possibilities.
  669. 4. Watch out for getting stuck in "local minima" if using #3.
  670.  
  671. Good luck!
  672. Dave
  673.  
  674. ---------------------------
  675.  
  676. From: aep@world.std.com (Andrew E Page)
  677. Subject: Directory Scan Revisited
  678. Date: 1 Sep 92 14:00:08 GMT
  679. Organization: The World Public Access UNIX, Brookline, MA
  680.  
  681.  
  682.     I'm just about finished with the code for the directory scan code.  I've
  683. incorporated some recomenedations from Apple, and I am in the process of
  684. commenting the code heavily.  
  685.  
  686.    However, here is the interface file.  Comments and suggestestions are
  687. welcome.  
  688.  
  689. - --------CUT HERE------------------------------------------------CUT HERE------
  690. #ifndef __DIRSCAN__
  691. #define __DIRSCAN__
  692. #ifndef __TYPES__
  693. #include <Types.h>
  694. #endif
  695.  
  696. Ptr StartDirScanDirID(short volRef, long dirID, int numTypes, OSType *TypeList, pascal Boolean (*filter)(FileParam *f)) ;
  697. /*
  698. *    StartDirScanDirID starts the directory scan, using a WDVRefNum.  
  699. *    It will return 0L if the call failed or a pointer to be used
  700. *    in subsequent calls.  
  701. *
  702. *
  703. *     volRef    true volume reference where scan is to start.
  704. *
  705. *            dirID            directory on volume where scan is to start.    
  706. *
  707. *     numTypes  Number of types to limit scan too.
  708. *               -1 indicates to scan all types.  
  709. *
  710. *     typeList  Array of OSTypes with numTypes elements.  
  711. *               Pass 0L if numTypes is -1
  712. *
  713. *     filter    Filter proc of the variety used by SFGetFile.  
  714. *               Pass 0L for no filtering.                 
  715. *
  716. *               pascal Boolean MyFilter(fileParamPtr *f) ;
  717. *                  MyFilter returns TRUE if file is to be excluded.
  718. *                    or FALSE if it isn't.   
  719. */
  720.  
  721. Ptr StartDirScanWDVRef(short vRef, short *volRef, int numTypes, OSType *TypeList, pascal Boolean (*filter)(FileParam *f)) ;
  722. /*
  723. *    StartDirScanWDVRef starts the directory scan, using a WDVRefNum.  
  724. *    It will return 0L if the call failed or a pointer to be used
  725. *    in subsequent calls.  
  726. *
  727. *
  728. *     vRef      Volume/Directory where scan is to start.
  729. *
  730. *            volRef        pointer a short where the true volume reference
  731. *                                number is to be placed when call is complete.  
  732. *
  733. *     numTypes  Number of types to limit scan too.
  734. *               -1 indicates to scan all types.  
  735. *
  736. *     typeList  Array of OSTypes with numTypes elements.  
  737. *               Pass 0L if numTypes is -1
  738. *
  739. *     filter    Filter proc of the variety used by SFGetFile.  
  740. *               Pass 0L for no filtering.                 
  741. *
  742. *               pascal Boolean MyFilter(fileParamPtr *f) ;
  743. *                  MyFilter returns TRUE if file is to be excluded.
  744. *                    or FALSE if it isn't.   
  745. */
  746.  
  747.  
  748. OSErr GetNextDirScanFile(Ptr scanPtr, char *fName, long *dirID, long *level) ;
  749. /*
  750. *     Each call to GetNextScanFile will retreive the next file in the
  751. *      directory tree.  GetNextScanFile will return a fnfErr when the
  752. *      scan is completed.  
  753. *
  754. *
  755. *  scanPtr     Ptr returned from StartScan
  756. *
  757. *  fName       string space for returned file name  (recommended length 64)
  758. *
  759. *  dirID        Pointer to a long where dirID reference for 
  760. *              the directory that the file is in.   
  761. *
  762. *     level                Pointer to a long where the level at which the file was found
  763. *               (0 is the level where the scan started).  You can pass a 0L
  764. *               in place of pointer if the level is not of interest.  
  765. *                            
  766. */
  767.  
  768. OSErr StopDirScan(Ptr scanPtr) ;
  769. /*
  770. *    Terminates the scan started by Start scan.  
  771. *
  772. *     scanPtr    Ptr returned by StartScan.  
  773. *
  774. *     CAUTION... do not not attempt to use scanPtr again
  775. *                after this call.  
  776. *
  777. */
  778.  
  779.  
  780. /*
  781. *   Using information returned from GetNextScanFile this function
  782. * will return a 'full pathname' as a handle.  The handle is the
  783. * exact length of the string and is NOT preceded by a pascal length
  784. * byte or folled by a C null terminator.  
  785. *
  786. *   fName      Name of the file.  
  787. *
  788. *        vRef       True volume reference number.
  789. *
  790. *   dirID      directory ID that the file resides in.  
  791. */
  792. Handle FullPathNameID(char *fName, int vRef, long dirID) ;
  793.  
  794. #endif
  795. - -- 
  796. Andrew E. Page CTO(Warrior Poet)|   Decision and Effort The Archer and Arrow
  797. DSP Ironworks                   |     The difference between what we are
  798. Macintosh and DSP Technology    |           and what we want to be.
  799.  
  800. +++++++++++++++++++++++++++
  801.  
  802. From: aep@world.std.com (Andrew E Page)
  803. Date: 2 Sep 92 19:04:54 GMT
  804. Organization: The World Public Access UNIX, Brookline, MA
  805.  
  806. Here is the directory scanning code.  Written under MPW 3.2.
  807.  
  808. - --------CUT HERE------------------------------------------------CUT HERE------
  809.  
  810. #ifdef USE_PRECOMPILE
  811. #pragma load ":Headers:dirscanh.hpc"
  812. #endif
  813.  
  814. #ifndef __ERRORS__
  815. #include <Errors.h>
  816. #endif
  817. #ifndef __FILES__
  818. #include <Files.h>
  819. #endif
  820. #ifndef __MEMORY__
  821. #include <Memory.h>
  822. #endif
  823. #ifndef __TOOLUTILS__
  824. #include <ToolUtils.h>
  825. #endif
  826. #ifndef __DIRSCAN__
  827. #include <dirscanh.h>
  828. #endif
  829.  
  830. #ifdef PRECOMPILE
  831. #undef PRECOMPILE
  832. #pragma dump ":Headers:dirscanh.hpc"
  833. #endif
  834.  
  835. /*
  836.  
  837.   dirscan.c by Andrew E. Page.    Macintosh Directory Scanning Code
  838.   The code operates as follows. 
  839.  
  840.   At the start of the scan StartScan accepts the directory in
  841.   which to start.  It initializes all the structures, starting
  842.   the scan in the directory at index 1, which is the first file
  843.   in the given directory.  For each call to GetNextScanFile the
  844.   file information for the current index is fetched, and the index
  845.   is incremented by one.  The entry is checked to see if it is
  846.   a directory.    If so the current state of the scan, the current
  847.   directory being scanned and the index for the next file, is pushed
  848.   onto a 'stack', and a recursive call to GetNextScanFile is made.    
  849.  
  850.  
  851.   If PBGetCatInfo returns a "File Not Found" error (-43 fnfErr) 
  852.   occurs during the scan the state of the stack is checked.  If
  853.   the stack is 'empty' (n_stackEntries == 0) then the scan is
  854.   at the top of the directory tree and has accessed the last
  855.   file, and the tree is exhasted.  Any other error should cause
  856.   the termination of the scan (this depends on how the code is
  857.   being used at a higher level however).
  858.   If the stack is not empty then the last entry is 'popped' off
  859.   of the stack and scanning resumes at that level.
  860.  
  861.  
  862. Example:
  863.  
  864. Consider the following directory tree.    With the vRefNum for <startdir>
  865. passed to StartScan, the files would be returned in the following
  866. order.    
  867.  
  868. file1a file1b file3a file3b file2a file2b file1c file4a
  869.  
  870.                      <startdir>
  871.                          |
  872.                          |
  873.                          |
  874.   file1a    file1b     <dir1a>   file1c    <dir1b>
  875.                         |                   |
  876.                         |                   |
  877.                         |                   |
  878.               <dir2a> file2a file2b        |
  879.                  |                           |
  880.                  |                           |
  881.                  |                           |
  882.            file3a file3b                   |
  883.                                            |
  884.                                            |
  885.                                         file4a
  886.                     
  887.  
  888.  
  889. */
  890.  
  891.  
  892. typedef struct {
  893.   long    dirID ; // the reference for the directory
  894.   short index ;  // what index it stopped scanning at
  895.   } StackEntry_t ;
  896.  
  897. typedef struct {
  898.   /*
  899.   * these fields provide
  900.   * control over the 'stack'.  Which
  901.   * saves the state of the scan from one
  902.   * level to the next.    
  903.   */
  904.   StackEntry_t    **entries ;       // container for the entries
  905.   long            n_stackEntries ;  // number of entries currently in stack
  906.   long            maxStackEntries ; // maximum entries stack can hold
  907.   long            level ;           // directory level we've decended to
  908.  
  909.   /*
  910.   * Storage space for the Parameter Block record.  This allows
  911.   * us to recycle certain fields without having to constantely
  912.   * reinitialize them.    
  913.   */
  914.   CInfoPBRec    F ;               // CInfo Rec ref IM IV-125
  915.  
  916.   /*
  917.   * filtering parameters
  918.   */
  919.   short       doFiltering ;       // is filtering necessary?
  920.   int          numTypes ;          // number of OSTypes to check for
  921.   OSType      *TypeList ;          // List of the types to check
  922.  
  923.   pascal Boolean (*filter)(FileParam *f) ; // filter function to be called for each file
  924.  
  925.   } ScanControl_t ;
  926.  
  927. /*
  928. *  We start off with a stack with a capacity for 32 entries.  Allowing
  929. *  us to descend 32 levels without having to reallocate any more memory.
  930. *  That should be sufficient for most applications.  However, more
  931. *  memory will be allocated if need be.  Each allocation will only
  932. *  require 192 additional bytes.
  933. *
  934. *  Season to taste here, just so long as STACK_BLOCK_INCREMENT >= 1
  935. */
  936. #define STACK_BLOCK_INCREMENT 32
  937.  
  938. /*
  939. * This is an internal function, hence the static qualifier. 
  940. * This provides the "push" or store function of a standard LIFO(Last In First Out)
  941. * queue.  Otherwise called a 'stack'.
  942. *
  943. *    Each time that it is called it stores the entry, in our case the directory
  944. * ID where the scan is 'branching' from, and the index in that directory where the
  945. * branch is taken, stores them in the container, and then increments the stack
  946. * pointer by one to make room for the next entry.  This differs slightly from the
  947. * nature of the 68XXX stack in as much as for a 68XXX stack the pointer is
  948. * predecremented to make space for the new entry.
  949. *
  950. *     Entries are retrieved from this stack with the PopFromStack function.    
  951. */
  952. static PushToStack(ScanControl_t *SC, long dirID, short index)
  953. {
  954.  
  955.   if( SC->n_stackEntries == SC->maxStackEntries )
  956.     {
  957.     /*
  958.     * Make room for more entries
  959.     */
  960.     SC->maxStackEntries += STACK_BLOCK_INCREMENT ;
  961.     SetHandleSize((Handle)SC->entries, sizeof(StackEntry_t) * SC->maxStackEntries) ;
  962.     }
  963.     
  964.   /*
  965.   * put the entry on the stack
  966.   */
  967.  
  968.   (*(SC->entries))[SC->n_stackEntries].dirID = dirID ;
  969.   (*(SC->entries))[SC->n_stackEntries].index = index ;
  970.  
  971.   SC->n_stackEntries += 1 ;
  972.   SC->level += 1 ;
  973.  
  974. } /* end of PushToStack */
  975.  
  976. /*
  977. * This is an internal function, hence the static qualifier. 
  978. * This provides the "pop" or retrieve function of a standard LIFO(Last In First Out)
  979. * queue.  Otherwise called a 'stack'.
  980. *
  981. *  Each time that it is called it restores the state of the scan from where
  982. * it had 'branched' in descending to another directory level.  It starts by
  983. * decrementing the 'stack pointer' so that it points at the last entry that was
  984. * placed on the stack by the PushToStack function.    
  985. */
  986. static PopFromStack(ScanControl_t *SC, long *dirID, short *index)
  987. {
  988.  
  989.   SC->n_stackEntries -= 1 ; 
  990.   SC->level -= 1 ;
  991.  
  992.   *index = (*(SC->entries))[SC->n_stackEntries].index ;
  993.   *dirID = (*(SC->entries))[SC->n_stackEntries].dirID ;
  994.  
  995. } /* end of PopFromStack */
  996.  
  997. #ifndef FALSE
  998. #define FALSE 0
  999. #define TRUE 1
  1000. #endif
  1001.  
  1002. /*
  1003. * This internal function determines whether or not this is a type
  1004. * of file that we are looking for.    It first checks the files 'type'
  1005. * against the list of types provided by the user, or simply passes it
  1006. * on if the numTypes was specified as -1.
  1007. *  If it succeeds in passing that check it then executes the 'filter' function
  1008. * if supplied by the caller.
  1009. */
  1010. static Boolean doFilter(ScanControl_t *SC, FileParam *f)
  1011. {
  1012. int i ;
  1013. short isType = FALSE ;
  1014.  
  1015.   /*
  1016.   * check against types
  1017.   */
  1018.  
  1019.   if( SC->numTypes != -1 )
  1020.     {
  1021.     for( i = 0 ; i < SC->numTypes ; i++ )
  1022.       {
  1023.       if( SC->TypeList[i] == f->ioFlFndrInfo.fdType )
  1024.         {
  1025.         isType = TRUE ;
  1026.         break ;
  1027.         }
  1028.       }
  1029.     /*
  1030.     * Is this one of the file types that we are looking for?
  1031.     * if not then exclude it from the list. 
  1032.     */
  1033.     if( !isType )
  1034.       return TRUE ;
  1035.     }
  1036.  
  1037.   /*
  1038.   * Perform any additional filtering with the
  1039.   * filter proc specified by the caller.
  1040.   */
  1041.   if( SC->filter )
  1042.     return (*SC->filter)(f) ;
  1043.  
  1044.  
  1045.   /*
  1046.   * Otherwise if we've reached this point
  1047.   * we do not want this filtered from the list
  1048.   */
  1049.   return FALSE ;
  1050.  
  1051. }
  1052.  
  1053.  
  1054. /*
  1055. *  This is essentially the core starting routine.  It will also be used
  1056. * when starting a scan with a WDVRef instead of a ioDirID.    
  1057. *
  1058. *  Initializes all the fields necessary, setting up the Parameter
  1059. * block for subsequent calls to GetNextDirScanFile. 
  1060. *
  1061. *  Sets up the Stack's controlling data structures, initializing the stack
  1062. * pointer to 0 and allocating an initial block of entries.    
  1063. *
  1064. *  Does some pre-filter checks to optimize for the case where no filtering
  1065. * is required.    It copies the TypeList to ensure that the data remains
  1066. * valid if this function is being called from a routine where the TypeList
  1067. * may reside in the stack frame that may be deallocated before calls to
  1068. * GetNextScanFile.    
  1069. *
  1070. */
  1071. Ptr StartDirScanDirID(short volRef, long dirID, int numTypes, OSType *TypeList, pascal Boolean (*filter)(FileParam *f))
  1072. {
  1073. ScanControl_t *SC ;
  1074. StackEntry_t **entries ;
  1075. OSType *theTypes ;
  1076. long len ;
  1077.  
  1078.   /*
  1079.   * Setup the control structure(s)
  1080.   * At each allocation check to ensure that we
  1081.   * got the space asked for.  If not, deallocate any
  1082.   * previous allocated memory and return a 0L, indictating
  1083.   * that the setup failed.    
  1084.   */
  1085.  
  1086.   /*
  1087.   * Check to see if the caller has provided a type list.
  1088.   * This will be the case if numTypes is > 0.
  1089.   * If so copy the list to ensure that it remains valid.
  1090.   */
  1091.   if( numTypes > 0 )
  1092.     {
  1093.     /*
  1094.     * Make space for the copy of the TypeList.    
  1095.     */
  1096.     theTypes = (OSType *)NewPtr(len = numTypes * sizeof(OSType)) ; // ref IM I-75
  1097.     if( theTypes == 0L )
  1098.       return 0L ;
  1099.     /*
  1100.     * copy the scan types    
  1101.     */
  1102.     BlockMove(TypeList, theTypes, len) ; // ref IM II-44
  1103.     }
  1104.   else
  1105.     theTypes = 0L ;
  1106.     
  1107.   /*
  1108.   * Allocate space for the stack.  Start off with STACK_BLOCK_INCREMENT
  1109.   * entries.  More can be added later if necessary. 
  1110.   */
  1111.   entries = (StackEntry_t **)NewHandle(sizeof(StackEntry_t) * STACK_BLOCK_INCREMENT) ; // ref IM I-76
  1112.   if( entries == 0L )
  1113.     {
  1114.     DisposPtr((Ptr)theTypes) ; // ref IM I-75
  1115.     return 0L ;
  1116.     }
  1117.  
  1118.   /*
  1119.   * Allocate space for the overal control structure that
  1120.   * will be passed back to the caller.    
  1121.   */
  1122.   SC = (ScanControl_t *)NewPtr(sizeof(ScanControl_t)) ; // ref IM I-75
  1123.   if( SC == 0L )
  1124.     {
  1125.     DisposPtr((Ptr)theTypes) ; // ref IM I-75
  1126.     DisposHandle((Handle)entries) ;
  1127.     return 0L ;
  1128.     }
  1129.     
  1130.   /*
  1131.   * Setup the filtering
  1132.   */
  1133.  
  1134.   if( (numTypes > 0) || (filter != 0L) )
  1135.     {
  1136.     SC->doFiltering = TRUE ;
  1137.     SC->numTypes = numTypes ;
  1138.     SC->TypeList = theTypes ;
  1139.     SC->filter = filter ;
  1140.     }
  1141.   else
  1142.     {
  1143.     SC->TypeList = 0L ;
  1144.     SC->doFiltering = FALSE ;
  1145.     }
  1146.     
  1147.   /*
  1148.   * initialize the current
  1149.   * state of the scan
  1150.   */
  1151.  
  1152.   SC->entries = entries ;
  1153.   SC->n_stackEntries = 0 ;
  1154.   SC->maxStackEntries = STACK_BLOCK_INCREMENT ;
  1155.   SC->level = 0 ;
  1156.  
  1157.   /*
  1158.   * Setup the initial PB Rec  ref IM IV-125
  1159.   */
  1160.  
  1161.   SC->F.hFileInfo.ioCompletion = 0L ; // always initialize this field!
  1162.   SC->F.hFileInfo.ioFlParID = dirID ; // Parent dirtory to start scan in.
  1163.   SC->F.hFileInfo.ioVRefNum = volRef ;// true volume reference number
  1164.   SC->F.hFileInfo.ioFDirIndex = 0 ;   // initial scanning index.  (will be incremented for each call)
  1165.  
  1166.   return (Ptr)SC ;
  1167.  
  1168. } /* end of StartDirScanDirID */
  1169.  
  1170. /*
  1171. *  This call allows us to start off with a WDVRef that may have been
  1172. * returned from SFGetFile.    It returns in volRef the true volume
  1173. * reference for the volume where the working directory passed in
  1174. * vRef resides. 
  1175. */
  1176. Ptr StartDirScanWDVRef(short vRef, short *volRef, int numTypes, OSType *TypeList, pascal Boolean (*filter)(FileParam *f))
  1177. {
  1178. OSErr err ;
  1179. WDPBRec wd ;
  1180.  
  1181.   /*
  1182.   * Setup the the wd parameter block
  1183.   */
  1184.  
  1185.   wd.ioCompletion = 0L ;
  1186.   wd.ioNamePtr = 0L ;
  1187.   wd.ioVRefNum = vRef ;
  1188.   wd.ioWDIndex = 0 ;
  1189.  
  1190.   /*
  1191.   * obtain the WD info
  1192.   */
  1193.  
  1194.   err = PBGetWDInfo(&wd, FALSE) ;
  1195.   if( err )
  1196.     return 0L ;
  1197.     
  1198.   *volRef = wd.ioWDVRefNum ; /* the true volume reference number */
  1199.  
  1200.   /*
  1201.   * use StartDirScanDirID to initialize the scan.
  1202.   */
  1203.   return StartDirScanDirID(wd.ioWDVRefNum, wd.ioWDDirID, numTypes, TypeList, filter) ;
  1204.     
  1205. } /* end of StartDirScan */
  1206.  
  1207.  
  1208. /*
  1209. * This function is essentially the core of the system.    Each call to this function
  1210. * will produce a file, or an fnfErr when the scan is completed.  Any other error is 
  1211. * an indication of something else being terribly wrong.
  1212. *
  1213. *  At each call the function will do the following:
  1214. *
  1215. *     1.  Increment the index of the file that is currently pointing at.
  1216. *
  1217. *     2.  Get the file's catalog information with PBGetCatInfo.
  1218. *
  1219. *     3.  If the file is a directory it will save the state of the scan on the
  1220. *         internal stack, and make a recursive call to itself to the next level. 
  1221. *
  1222. *     4.  If PBGetCatInfo returns with a File Not Find Error (fnfErr -43), it pops
  1223. *         the last entry off of the stack, restoring the state of the scan and makes
  1224. *         a recursive call to itself to return to the previous level.  If the stack
  1225. *         at this point is empty it returns the fnfErr to the caller indicating that
  1226. *         the scan has completed.
  1227. *
  1228. *     5.  If the file entry is not a directory it checks it against the types and
  1229. *         filter function specified by the caller.  If it is rejected by the filter, 
  1230. *         (when it returns TRUE) GetNextDirScanFile repeats steps 1 through 4.
  1231. */
  1232. OSErr GetNextDirScanFile(Ptr scanPtr, char *fName, long *dirID, long *level)
  1233. {
  1234. ScanControl_t *SC = (ScanControl_t *)scanPtr ;
  1235. OSErr err ;
  1236. short flag = FALSE ;
  1237. long parID = SC->F.hFileInfo.ioFlParID ;
  1238.  
  1239.   SC->F.hFileInfo.ioNamePtr = fName ;
  1240.  
  1241.   do {
  1242.     SC->F.hFileInfo.ioFDirIndex++ ;
  1243.     SC->F.hFileInfo.ioDirID = parID ;
  1244.     err = PBGetCatInfo(&SC->F, FALSE) ;
  1245.     if( err )
  1246.       {
  1247.       /*
  1248.       * Anything other than a fnfErr, or a noErr is an inidcation
  1249.       * of some catastrophic failure and that the scan cannot procede.
  1250.       */
  1251.       if( err != fnfErr )
  1252.         return err ;
  1253.         
  1254.       /*
  1255.       * if there is an fnfErr and there are no more stack entries, this means
  1256.       * that the tree that is being searched has been exhausted.  Returning
  1257.       * the fnfErr at this point should terminate the scan by the caller.
  1258.       */
  1259.       if( SC->n_stackEntries == 0 )
  1260.         return err ;
  1261.     
  1262.       /*
  1263.       * if it is a fnfErr, and entries remain in the stack, we have exhausted
  1264.       * the file entries at this level and need to return to the previous level
  1265.       * and resuming scanning where  we left off.  To do this we Pop the previous
  1266.       * state of the scan  off of the stack, and make a recursive call to GetNextDirScanFile.
  1267.       */
  1268.       PopFromStack(SC, &SC->F.hFileInfo.ioFlParID, &SC->F.hFileInfo.ioFDirIndex) ;
  1269.             
  1270.       return GetNextDirScanFile((Ptr)SC, fName, dirID, level) ;
  1271.       }
  1272.  
  1273.     if( SC->F.hFileInfo.ioFlAttrib & 0x10 ) // check for directory flag
  1274.       {
  1275.       /*
  1276.       * Save the state of the scan
  1277.       * at the current level.
  1278.       */
  1279.       PushToStack(SC, SC->F.dirInfo.ioDrParID, SC->F.hFileInfo.ioFDirIndex) ;
  1280.     
  1281.       /*
  1282.       * Setup the the state of the next level to be
  1283.       * the directory that we just found.  Starting at the
  1284.       * first file index.
  1285.       */
  1286.       SC->F.hFileInfo.ioFlParID = SC->F.dirInfo.ioDrDirID ;
  1287.       SC->F.hFileInfo.ioFDirIndex = 0 ;
  1288.     
  1289.       return GetNextDirScanFile((Ptr)SC, fName, dirID, level) ;
  1290.       }
  1291.  
  1292.     /*
  1293.     * if necessary check to see if we should filter
  1294.     * out this file entry.    
  1295.     */
  1296.     
  1297.     if( SC->doFiltering )
  1298.       flag = doFilter(SC, (FileParam *)&SC->F) ;
  1299.     } while( flag ) ; // if file is to be filtered, try another one.
  1300.     
  1301.   /*
  1302.   * Set the directory ID parameter
  1303.   */
  1304.   *dirID = SC->F.hFileInfo.ioFlParID ;
  1305.  
  1306.   /*
  1307.   * if the caller wants the level of this file set it.
  1308.   */
  1309.   if( level )
  1310.     *level = SC->level ;
  1311.     
  1312.   return err ;
  1313.  
  1314. } /* end of GetNextDirScanFile */
  1315.  
  1316.  
  1317. /*
  1318. * This terminates the scan.  What is actually does is release
  1319. * all the memory that was allocated.  Since no new working
  1320. * directories were created there is no need to call PBCloseWD.
  1321. */
  1322. OSErr StopDirScan(Ptr scanPtr)
  1323. {
  1324. ScanControl_t *SC = (ScanControl_t *)scanPtr ;
  1325.  
  1326.   if( SC->TypeList )
  1327.     DisposPtr((Ptr)SC->TypeList) ;
  1328.  
  1329.   DisposHandle((Handle)SC->entries) ;
  1330.   DisposPtr(scanPtr) ;
  1331.  
  1332.   /*
  1333.   * Although it is unlikely that we will have comitted
  1334.   * any errors provide this check to the caller.
  1335.   */
  1336.   return MemError() ;
  1337. }
  1338.  
  1339. /*
  1340. *
  1341. * This function will generate a full pathname to
  1342. * the file identified by its name, volume, and directory ID.
  1343. * The result is a handle that contains the full pathname of the
  1344. * file and is sized to fit that pathname exactly.  It contains
  1345. * No length byte or null terminator.  The length of the string can
  1346. * be determined with GetHandleSize. 
  1347. *
  1348. *
  1349. * The function operates as a loop.    At each interation through the
  1350. * the loop it gets the catalog name for the entry.    Each time
  1351. * making the parent directory for that entry the target for the
  1352. * next cycle.  This proceeds until it hits the root directory
  1353. * is reached, which has no logical parent, and thus PBGetCatInfo
  1354. * returned a file not found error(-43 fnfErr).
  1355. *
  1356. *     We use a handle since this allows us to use the
  1357. * Munger string manipulator.
  1358. *
  1359. */
  1360.  
  1361. Handle FullPathNameID(char *fName, int vRef, long dirID)
  1362. {
  1363. Handle theString = NewHandle(0) ; /* container for the string */
  1364. CInfoPBRec F ;
  1365. short err ;
  1366. char colon = ':' ; /* just in case you want to put it into a stand alone code resource */
  1367. char string[64] ;
  1368.  
  1369.   /*
  1370.   * For safety sake(to ensure that our string contains enough space for 
  1371.   * subsequent entries found, and to make sure that we don't overwrite
  1372.   * the input string, we copy the input fileName to our own storage.
  1373.   */
  1374.  
  1375.   BlockMove(fName, string, fName[0]+1) ; // ref IM II-44
  1376.  
  1377.   /*
  1378.   * Initialize the PB fields
  1379.   */
  1380.  
  1381.   F.hFileInfo.ioNamePtr = string ;    /* pascal string for the name, and also subsequent storage on calls */
  1382.   F.hFileInfo.ioVRefNum = vRef ;  /* volume reference (Gotten from SFGetFile perhaps */
  1383.   F.hFileInfo.ioCompletion = 0L ; /* initialize this field or get a Serious BOMB */
  1384.   F.hFileInfo.ioFDirIndex = 0 ;   /* for the first call only.  Get CatInfo based on ioNamePtr, ioVRefNum, and dirID */
  1385.   F.hFileInfo.ioDirID = dirID ;   /* directory containing this file */
  1386.  
  1387.   while( !(err = PBGetCatInfo(&F,0)) )
  1388.     {
  1389.     /*
  1390.     * Insert the directory level into the front of the string
  1391.     */
  1392.     Munger(theString, 0, 0L, 0, &string[1], string[0]) ; // ref IM I-468
  1393.  
  1394.     /*
  1395.     * Insert a colon in front of the Directory Entry
  1396.     */
  1397.     Munger(theString, 0, 0L, 0, &colon, 1) ; // ref IM I-468
  1398.  
  1399.     /*
  1400.     * We now wish to get the information about
  1401.     * the directory that contains this file/directory.
  1402.     * in short we are moving one level UP in the heirarchy
  1403.     */
  1404.     F.dirInfo.ioDrDirID = F.dirInfo.ioDrParID ; /* get the ioDrDirID of the PARENT directory (the next level up) */
  1405.     
  1406.     /*
  1407.     * Setting this field to < 0 will
  1408.     * cause PBGetCatInfo to get the catalog
  1409.     * information based on the VRef and dirID
  1410.     * that we've placed in F.dirInfo.ioDrDirID,
  1411.     * and return the name of the entry in the
  1412.     * pointer to the string in ioNamePtr.
  1413.     */
  1414.     F.hFileInfo.ioFDirIndex = -1 ;
  1415.     }
  1416.     
  1417.   /*
  1418.   * The last entry will be the Volume name which should not have a colon in front of it
  1419.   */
  1420.     
  1421.   Munger(theString, 0, 0L, 1, string, 0) ;
  1422.  
  1423.   return theString ;
  1424. }
  1425.  
  1426.  
  1427. - -- 
  1428. Andrew E. Page CTO(Warrior Poet)|   Decision and Effort The Archer and Arrow
  1429. DSP Ironworks                   |     The difference between what we are
  1430. Macintosh and DSP Technology    |           and what we want to be.
  1431.  
  1432. ---------------------------
  1433.  
  1434. End of C.S.M.P. Digest
  1435. **********************
  1436.